﻿using System;
using System.Windows;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Media;
using Bling.DSL;
using Bling.WPF;
using Bling.WPF.Util;
using Bling.Core;
using Bling.Util;
using Bling.Physics.UI;
using Bling.Physics;
using Bling.Properties;
using Bling.Mixins;
using Bling.Blocks;
using Bling.Shapes;

namespace Bling.Tutorial {
  public class RectBlock : TopBlock<RectBlock, PathShapeBl>, HasShape.IHas<RectBlock>, MouseInput.IHas<RectBlock, PathShapeBl> {
    public RectBlock(BlockManager Manager, CanvasBl Canvas, int Count) : base(Manager, Count, (block,idx) => {
        return new PathShapeBl(Canvas) {
          Fill = idx.SelectColor(), 
        };
      }) { }
  }

  public class ThumbBlock : TopBlock<ThumbBlock,ThumbBl>, HasPosition.IHas<ThumbBlock> {
    public ThumbBlock(BlockManager Manager, CanvasBl Canvas, int Count) : base(Manager, Count, (block,idx) => {
        return new ThumbBl(Canvas) {
          Background = idx.SelectColor(), CanDrag = true, Size = new PointBl(10,10),
        };
      }) { }
  }
  public class PhysicsTest : PhysicsCanvas {
    protected override Action Init(CanvasBl MainCanvas, BlockManager Manager) { // executes before blocks are initialized.
      MainCanvas.Background = Brushes.White;
      if (true) {
        var Block = new ThumbBlock(Manager, MainCanvas, 100);
        var r = new Random();
        Block.ForAll = Elem => {
          Elem.Position().Init = ((PointBl)r) * new PointBl(500, 500);
          Elem.Position().InstallVerletStep(.01);
          Elem.Position().Link[!Elem.At.IsDragging] = Elem.At.CenterPosition;
          Elem.Position().Relax[.01] = Elem.Position().Clamp(new PointBl(0, 0), MainCanvas.Size);

          Elem.Position().Distance(Elem.Prev[1].Position()).Relax[1d] = 10d;
          /*
          Elem.Position().Distance(Elem.Prev[2].Position()).Relax[.5, Elem.Index > 1] = 60d;
          Elem.Position().Distance(Elem.Prev[2].Position()).Relax[.25, Elem.Index > 2] = 90d;
          Elem.Position().Distance(Elem.Prev[2].Position()).Relax[.125, Elem.Index > 3] = 120d;
           */
        };
        //Block[0].Position().Link[!MainCanvas.IsMouseOver] = MainCanvas.MousePosition.NoAssign;
      }
      if (false) {
        var Block = new RectBlock(Manager, MainCanvas, 25);
        var r = new Random();
        Block.ForAll = body => {
          body.Particles().ForAll = particle => {
            particle.Position.Init = r * new PointBl(500, 500);
          };
        };

        Block.HasShapeE().SetSize(100d);
        Block.HasShapeE().AddRelaxCenter = (target) => {
          Block.ForAll = body => body.Rotation().Relax[0.01] = VecAngle2DBl.Default;
        };

        var Thumbs = new ThumbBlock(Manager, MainCanvas, Block.Count * HasParticles.Mixin<RectBlock>.ParticleCount);
        Block.AfterMixins = () => {
          Block.ForAll = body => {
            body.Particles().ForAll = particle => {
              var thumb = Thumbs[body.Index * HasParticles.Mixin<RectBlock>.ParticleCount + particle.Index].At;
              particle.Position.Link[!thumb.IsDragging] = thumb.CenterPosition;
              particle.Position.InstallVerletStep(.01);
              particle.Position.Relax[.1] = particle.Position.Clamp(new PointBl(0, 0), MainCanvas.Size);
            };
          };
        };
        return () => {
          for (int j = 0; j < Block.Count; j++) {
            Block[j].At.Start = Thumbs[j * HasParticles.Mixin<RectBlock>.ParticleCount + 0].At.CenterPosition;
            for (int i = 0; i < HasParticles.Mixin<RectBlock>.ParticleCount; i++) {
              Block[j].At.Segments.AddOne = new LineSegmentBl() {
                Point = Thumbs[j * HasParticles.Mixin<RectBlock>.ParticleCount + (i + 1) % HasParticles.Mixin<RectBlock>.ParticleCount].At.CenterPosition
              };

            }
          }
          for (int i = 0; i < Thumbs.Count; i++) {
            Thumbs[i].At.Background = (i % HasParticles.Mixin<RectBlock>.ParticleCount).SelectColor();
            Thumbs[i].At.Size = new PointBl(10, 10);
          }

        };
      }
      return () => { };
    }

  }
}